#ifndef __CIRCLE_HPP
#define __CIRCLE_HPP

#include "base/Graphic.hpp"

using namespace std;

namespace model {

using base::graphic::Point;
using utils::EasyMatrix;

template<class PixelType> class Circle: public base::Graphic<PixelType> {
	
	protected:Point    center;
	protected:unsigned r;
	
	public:Circle(Integer x, Integer y, unsigned _r): center{x, y}, r{_r} {
	}
	
	public:Circle(const Circle& another): center(another.center), r(another.r) {
	}
};

class CharCircle: public Circle<char> {
	
	private:char pixelChar;
	private:EasyMatrix<Float> tranMatrix;

	public:CharCircle(Integer x, Integer y, unsigned _r, char pixel = '+'):
		Circle(x, y, _r), tranMatrix(EasyMatrix<Float>::EYE(4)) {
		pixelChar = pixel;
		draw();
	}

	//中点画圆法
	protected:void draw() {
		drawCircle(*this, center, r, pixelChar, &tranMatrix);
	}
	
	protected:static void drawCircle(base::Graphic<char>& graphic, Point center, Integer r, char pixelChar, const EasyMatrix<Float>* tranlater = nullptr) {
		
		Integer x = 0, y = r;
		Float d = 1.25 - r;
		
		Pixel p;
		p.setPixel(pixelChar);
		p.setX(x);
		p.setY(y);
		
		drawCirclePoints(graphic, center, p, tranlater);

		while(x <= y) {
			if(d < 0) d += (x<<1) + 3;
			else {
				d += ((x-y)<<1) + 5; --y;
			}
			++x;
			p.setX(x);
			p.setY(y);
			drawCirclePoints(graphic, center, p, tranlater);
		}
	}
	
	//8对称标点
	private:static void drawCirclePoints(base::Graphic<char>& graphic, Point center, Pixel p, const EasyMatrix<Float>* tranlater = nullptr) {

		int x = p.getX(), y = p.getY();
		
		p.setX(x + center.x);
		p.setY(y + center.y);
		if(tranlater) p.translate(*tranlater);
		graphic.putPixel(p);

 		p.setX(y + center.x);
  		p.setY(x + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(-x + center.x);
  		p.setY(y + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(y + center.x);
  		p.setY(-x + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(x + center.x);
  		p.setY(-y + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(-y + center.x);
  		p.setY(x + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(-x + center.x);
  		p.setY(-y + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);

  		p.setX(-y + center.x);
  		p.setY(-x + center.y);
		if(tranlater) p.translate(*tranlater);
  		graphic.putPixel(p);
	}
	
	public:Graphic& translate(const EasyMatrix<Float>& matrix) {
		tranMatrix = matrix * tranMatrix;
		clear();
		draw();
		rebuff();
		return *this;
	}
};

};
#endif

/*
	//中点画圆法
	protected:void draw() {

		Integer x = 0, y = r;
		Float d = 1.25 - r;

		circlePoints(x, y, pixelChar);

		while(x <= y) {
			if(d < 0) d += (x<<1) + 3;
			else {
				d += ((x-y)<<1) + 5; --y;
			}
			++x;
			circlePoints(x, y, pixelChar);
		}
	}

	//8对称标点
	private:void circlePoints(Integer x, Integer y, char pc) {
		Pixel p(x + center.x, y + center.y, pc);
		putPixel(p);

		p.setX(y + center.x);
		p.setY(x + center.y);
		putPixel(p);

		p.setX(-x + center.x);
		p.setY(y + center.y);
		putPixel(p);

		p.setX(y + center.x);
		p.setY(-x + center.y);
		putPixel(p);

		p.setX(x + center.x);
		p.setY(-y + center.y);
		putPixel(p);

		p.setX(-y + center.x);
		p.setY(x + center.y);
		putPixel(p);

		p.setX(-x + center.x);
		p.setY(-y + center.y);
		putPixel(p);

		p.setX(-y + center.x);
		p.setY(-x + center.y);
		putPixel(p);
	}

*/
